<?php

namespace App\Http\Controllers\Api\Scenic;

use App\Http\Controllers\Controller;
use App\Models\Common\Area\Area;
use App\Models\Common\Area\Repositories\Interfaces\AreaRepositoryInterface;
use App\Models\Orders\Orders;
use App\Models\Scenic\Order\ScenicOrderGoods;
use App\Models\Scenic\ScenicOrder;
use App\Models\Scenic\ScenicSpotProvider;
use App\Services\Scenic\Query\ScenicQueryFactoryInterface;
use App\Services\Scenic\ScenicQueryFactory;
use App\Trip\Enums\Scenic\ScenicProvider;
use App\Trip\Geo\Location;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ScenicController extends Controller
{

    private AreaRepositoryInterface $areaRepo;
    private ScenicQueryFactoryInterface $scenicQuery;

    public function __construct(
        AreaRepositoryInterface $areaRepository,
        Request $request
    )
    {
        $providerValue = $request->input('provider',ScenicProvider::TUNIU->value);
        $provider = (ScenicProvider::from($providerValue));
        $this->scenicQuery = (new ScenicQueryFactory())->findOneByProvider($provider);
        $this->areaRepo = $areaRepository;
    }

    /**
     * 景点列表
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \Exception
     *
     */
    public function list(Request $request)
    {
        $page = $request->input('page') ?? 1;
        $pageSize = $request->input('page_size') ?? 10;
        $citycode = $request->input('citycode');
        $location = $request->input('location');
        //获取的服务商,目前默认走途牛
        $sort = $request->input('sort') ?? [];
        if (empty($citycode)) {
            return $this->error(404, '参数错误');
        }
        if (empty($sort)) {
            $sort = [
                'key' => 'distance',
                'value' => 1,
            ];
        }
        if (!in_array($sort['key'], ['distance', 'rating'])) {
            return $this->error(404, '排序参数错误');
        }
        if (!in_array($sort['value'], [1])) {
            return $this->error(404, '排序参数错误');
        }
        $city = $this->areaRepo->findByCode($citycode);
        if (!$city instanceof Area) {
            return $this->error(404, '城市编码参数错误');
        }
        if (!$location) {
            $location = $city->center;
        }
        //走途牛的话，关键词用区域名称代替
        $keyword = $city->getAreaName();
        $locationData = new Location($location);
        try {
            $resp = $this->scenicQuery->list($keyword,$page,$pageSize,$sort,$locationData);
        }catch (\Exception $exception){
            return $this->error(404,$exception->getMessage());
        }

        return $this->success('success', $resp);
    }

    /**
     * 推荐景点
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function recommend(Request $request)
    {
        $limit = $request->input('limit') ?? 6;
        $location = $request->input('location');
        $locationData = new Location($location);
        try {
            $scenicQuery = (new ScenicQueryFactory())->findOneByProvider(ScenicProvider::LOCAL);
            $data = $scenicQuery->recommend($limit,$locationData);
        }catch (\Exception $exception){
            return $this->error(404,$exception->getMessage());
        }
        $resp = [
            'scenic_spots' => $data,
        ];
        return $this->success('success', $resp);
    }


    /**
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function popular(Request $request)
    {
        $limit = $request->input('limit') ?? 6;
        $location = $request->input('location');
        $locationData = new Location($location);
        try {
            $scenicQuery = (new ScenicQueryFactory())->findOneByProvider(ScenicProvider::LOCAL);
            $data = $scenicQuery->recommend($limit,$locationData);
        }catch (\Exception $exception){
            return $this->error(404,$exception->getMessage());
        }
        $resp = [
            'scenic_spots' => $data,
        ];
        return $this->success('success', $resp);
    }


    /**
     * 景点搜索
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function search(Request $request)
    {
        $requestdata = $request->all();
        $citycode = $requestdata['citycode'] ?? '';
        $cityname = $requestdata['cityname'] ?? '';
        $inputLocation = $requestdata['location'] ?? '';
        $keyword = $requestdata['keyword'] ?? '';
        if (empty($keyword) || empty($citycode)) {
            return $this->error(404, '参数错误');
        }
        $city = $this->areaRepo->findByCode($citycode);
        if (!$city instanceof Area) {
            throw new \Exception(404, '城市编码参数错误');
        }

        try {
            $resp = $this->scenicQuery->search($keyword,$citycode,$inputLocation);
        }catch (\Exception $exception){
            return $this->error(404,$exception->getMessage());
        }

        return $this->success('success', $resp);
    }

    /**
     * 景点详情
     * @param string $id
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function show(string $id, Request $request)
    {
        $inputLocationStr = $request->input('location');
        $inputLocation = null;
        if (!empty($inputLocationStr)) {
            $inputLocation = new Location($inputLocationStr);
        }

        $spotProvider = ScenicSpotProvider::where('scenic_id',$id)->first();
        if ($spotProvider instanceof ScenicSpotProvider){
            $provider = (ScenicProvider::from($spotProvider->provider));
            $this->scenicQuery = (new ScenicQueryFactory())->findOneByProvider($provider);
            $providerScenicId = $spotProvider->provider_scenic_id;
        }else{
            $providerScenicId = $id;
        }

        try {
            $data = $this->scenicQuery->detail($providerScenicId,$inputLocation);
        }catch (\Exception $exception){
            return $this->error(404,$exception->getMessage());
        }

        $data['scenic_id'] = $id;
        return $this->success('success', ['scenic_spot' => $data]);
    }

}
